/*
 *  NachoCalendar
 *
 * Project Info:  http://nachocalendar.sf.net
 *
 * This library is free software; you can redistribute it and/or modify it
 * under the terms of the GNU Lesser General Public License as published by the
 * Free Software Foundation;
 * either version 2.1 of the License, or (at your option) any later version.
 *
 * This library is distributed in the hope that it will be useful, but WITHOUT
 * ANY WARRANTY;
 * without even the implied warranty of MERCHANTABILITY or FITNESS FOR A
 * PARTICULAR PURPOSE.
 * See the GNU Lesser General Public License for more details.
 *
 * You should have received a copy of the GNU Lesser General Public License
 * along with this library; if not, write to the Free Software Foundation, Inc.,
 * 59 Temple Place, Suite 330, Boston, MA 02111-1307, USA.
 *
 * [Java is a trademark or registered trademark of Sun Microsystems, Inc. 
 * in the United States and other countries.]
 *
 * Changes
 * -------
 *
 * 2005-01-09   Cleanups
 * 2004-12-11   Fixed setYear, now accepts years from 0 to 2100   
 * 2004-10-22   setEnabled(boolean b) overriden, now works
 * 2004-10-18   Changed the formatter for a MaskFormatter
 * 2004-10-01   Checked with checkstyle
 * 2004-9-3     Fixed borders
 *
 * -------
 * YearScroller.java
 *
 * Created on August 12, 2004, 6:47 PM
 */

package net.sf.nachocalendar.components;

import java.awt.GridBagConstraints;
import java.util.Calendar;

import javax.swing.Icon;
import javax.swing.JButton;
import javax.swing.JFormattedTextField;
import javax.swing.SwingConstants;
import javax.swing.border.Border;
import javax.swing.event.ChangeEvent;
import javax.swing.text.MaskFormatter;

/**
 * Component used to change the current year. It extends from JComboBox and has
 * two arrows for unitary changes. It fires a ChangeEvent when the year is
 * changed.
 * 
 * @author Ignacio Merani
 */
public class YearScroller extends javax.swing.JPanel {
  private static final long serialVersionUID = -5625598683420096612L;
  private JButton bNext;
  private JButton bPrevious;
  private JFormattedTextField tYear;

  /** Creates new form YearScroller. */
  public YearScroller() {
    initComponents();
    Calendar cal = Calendar.getInstance();
    tYear.setValue(new Integer(cal.get(Calendar.YEAR)));
    Border border = tYear.getBorder();
    tYear.setBorder(null);
    setBorder(border);
  }

  /**
   * This method is called from within the constructor to initialize the form.
   * WARNING: Do NOT modify this code. The content of this method is always
   * regenerated by the Form Editor.
   */
  private void initComponents() {
    GridBagConstraints gridBagConstraints;

    bPrevious = new ArrowButton(SwingConstants.WEST);
    try {
      tYear = new javax.swing.JFormattedTextField(new MaskFormatter("####"));
    } catch (Exception e) {
      e.printStackTrace();
    }
    bNext = new ArrowButton(SwingConstants.EAST);

    FormListener formListener = new FormListener();

    setLayout(new java.awt.GridBagLayout());

    bPrevious.addActionListener(formListener);

    gridBagConstraints = new java.awt.GridBagConstraints();
    gridBagConstraints.fill = java.awt.GridBagConstraints.BOTH;
    gridBagConstraints.weighty = 1.0;
    add(bPrevious, gridBagConstraints);

    tYear.setColumns(4);
    tYear.setHorizontalAlignment(SwingConstants.CENTER);
    tYear.addActionListener(formListener);

    gridBagConstraints = new java.awt.GridBagConstraints();
    gridBagConstraints.fill = java.awt.GridBagConstraints.BOTH;
    gridBagConstraints.weightx = 1.0;
    gridBagConstraints.weighty = 1.0;
    add(tYear, gridBagConstraints);

    bNext.addActionListener(formListener);

    gridBagConstraints = new java.awt.GridBagConstraints();
    gridBagConstraints.fill = java.awt.GridBagConstraints.BOTH;
    gridBagConstraints.weighty = 1.0;
    add(bNext, gridBagConstraints);

  }

  private class FormListener implements java.awt.event.ActionListener {
    public void actionPerformed(java.awt.event.ActionEvent evt) {
      if (evt.getSource() == bPrevious) {
        YearScroller.this.bPreviousActionPerformed(evt);
      } else if (evt.getSource() == tYear) {
        YearScroller.this.tYearActionPerformed(evt);
      } else if (evt.getSource() == bNext) {
        YearScroller.this.bNextActionPerformed(evt);
      }
    }
  }

  private void tYearActionPerformed(java.awt.event.ActionEvent evt) {
    fireChangeListenerStateChanged(new ChangeEvent(this));
  }

  private void bNextActionPerformed(java.awt.event.ActionEvent evt) {
    setYear(getYear() + 1);
    fireChangeListenerStateChanged(new ChangeEvent(this));
  }

  private void bPreviousActionPerformed(java.awt.event.ActionEvent evt) {
    setYear(getYear() - 1);
    fireChangeListenerStateChanged(new ChangeEvent(this));
  }

  /**
   * Changes the icon for the Next button.
   * 
   * @param icon
   *          new Icon or null to show the default arrow
   */
  public void setNextIcon(Icon icon) {
    bNext.setIcon(icon);
  }

  /**
   * Changes the icon for the Previous button.
   * 
   * @param icon
   *          new Icon or null to show the default arrow
   */
  public void setPreviousIcon(Icon icon) {
    bPrevious.setIcon(icon);
  }

  /**
   * Changes the text of the Next button.
   * 
   * @param text
   *          new text or null to show the default arrow
   */
  public void setNextText(String text) {
    bNext.setText(text);
  }

  /**
   * Changes the text of the Previous button.
   * 
   * @param text
   *          new text or null to show the default arrow
   */
  public void setPreviousText(String text) {
    bPrevious.setText(text);
  }

  /**
   * Returns the current selected year.
   * 
   * @return current year
   */
  public int getYear() {
    return ((Number) tYear.getValue()).intValue();
  }

  /**
   * Changes the current selected year.
   * 
   * @param year
   *          current year
   */
  public void setYear(int year) {
    if ((year > 0) && (year < 2100)) {
      tYear.setValue(new Integer(year));
    }
  }

  /**
   * Registers ChangeListener to receive events.
   * 
   * @param listener
   *          The listener to register.
   */
  public synchronized void addChangeListener(javax.swing.event.ChangeListener listener) {
    if (changeListenerList == null) {
      changeListenerList = new java.util.ArrayList();
    }
    changeListenerList.add(listener);
  }

  /**
   * Removes ChangeListener from the list of listeners.
   * 
   * @param listener
   *          The listener to remove.
   */
  public synchronized void removeChangeListener(javax.swing.event.ChangeListener listener) {
    if (changeListenerList != null) {
      changeListenerList.remove(listener);
    }
  }

  /**
   * Notifies all registered listeners about the event.
   * 
   * @param event
   *          The event to be fired
   */
  private void fireChangeListenerStateChanged(javax.swing.event.ChangeEvent event) {
    java.util.ArrayList list;
    synchronized (this) {
      if (changeListenerList == null) {
        return;
      }
      list = (java.util.ArrayList) changeListenerList.clone();
    }
    for (int i = 0; i < list.size(); i++) {
      ((javax.swing.event.ChangeListener) list.get(i)).stateChanged(event);
    }
  }

  /**
   * Enables or disables the component.
   * 
   * @param b
   *          true for enabling
   */
  public void setEnabled(boolean b) {
    bNext.setEnabled(b);
    bPrevious.setEnabled(b);
    tYear.setEnabled(b);
  }

  /**
   * Getter for enabled property.
   * 
   * @return true if it's enabled
   */
  public boolean isEnabled() {
    if (tYear == null)
      return false;
    return tYear.isEnabled();
  }

  /**
   * Utility field holding list of ChangeListeners.
   */
  private transient java.util.ArrayList changeListenerList;

}
